﻿using System.Collections.Concurrent;

namespace System.Erp.Runtime.Services
{
    /// <summary>
    /// 默认实现的服务容器，能够管理服务与创建者的关系，以及在申请服务时提供实例。
    /// </summary>
    public sealed class CompositionServiceContainer : CompositionServiceProviderBase, ICompositionServiceContainer
    {
        private readonly ConcurrentDictionary<CompositionServiceKey, ICreator> _dictCreators;

        /// <summary>
        /// 创建默认的 CompositionServiceContainer 实例
        /// </summary>
        public CompositionServiceContainer()
        {
            _dictCreators = new ConcurrentDictionary<CompositionServiceKey, ICreator>();
        }

        /// <summary>
        /// 向容器中添加指定服务接口的创建者
        /// </summary>
        /// <param name="key">服务键</param>
        /// <param name="creator">创建者实例</param>
        public void Add(CompositionServiceKey key, ICreator creator)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (creator == null)
            {
                throw new ArgumentNullException("creator");
            }

            if (!_dictCreators.TryAdd(key, creator))
            {
                throw new ArgumentException(string.Format("添加的服务{0}已经存在对应的实现。请检查。", key));
            }
        }

        /// <summary>
        /// 检查某个服务实现是否存在
        /// </summary>
        /// <param name="key">要检查的服务键</param>
        /// <returns>如果存在则返回true，否则返回false</returns>
        public bool ContainsKey(CompositionServiceKey key)
        {
            return _dictCreators.ContainsKey(key);
        }

        /// <summary>
        /// 删除指定服务键的创建者
        /// </summary>
        /// <param name="key">要删除的服务键</param>
        /// <returns>如果此服务键已经存在于容器并成功删除，返回true，否则返回false</returns>
        public bool Remove(CompositionServiceKey key)
        {
            ICreator creator;
            return _dictCreators.TryRemove(key, out creator);
        }

        /// <summary>
        /// 根据当前请求获取对象的创建者对象
        /// </summary>
        /// <param name="serviceKey">服务请求对象描述</param>
        /// <param name="creator">如果对象的实现，将返回他，否则返回null</param>
        /// <returns>是否成功找到创建者对象</returns>
        protected override bool TryGetCreator(CompositionServiceKey serviceKey, out ICreator creator)
        {
            return _dictCreators.TryGetValue(serviceKey, out creator);
        }

        /// <summary>
        /// 删除服务容器中的所有实现。
        /// </summary>
        public void Clear()
        {
            _dictCreators.Clear();
        }
    }
}